<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="yiYrj" id="yiYrj"><span data-lake-id="u763ae26a" id="u763ae26a" style="color: rgb(36, 41, 47)">典型回答</span></h1>
  <p data-lake-id="u02f9db9c" id="u02f9db9c"><br></p>
  <p data-lake-id="ue66c6f0e" id="ue66c6f0e"><span data-lake-id="ua80ccb04" id="ua80ccb04">所谓数据库范式，其实就是数据库的设计上的一些规范；这些规范可以让数据库的设计更加简洁、清晰；同时也会更加好的可以保证一致性。</span></p>
  <p data-lake-id="u1d3dc92d" id="u1d3dc92d"><br></p>
  <p data-lake-id="u753662c8" id="u753662c8"><span data-lake-id="u6cf176be" id="u6cf176be">三个常用的范式：</span></p>
  <ul list="ue3a00ff8">
   <li fid="u8bee48ee" data-lake-id="ua68b3fa8" id="ua68b3fa8"><span data-lake-id="u14a7b50d" id="u14a7b50d">第一范式（1NF）是说，数据库表中的属性的原子性的，要求属性具有原子性，不可再被拆分；</span></li>
  </ul>
  <ul list="ue3a00ff8" data-lake-indent="1">
   <li fid="u10822075" data-lake-id="u11936c14" id="u11936c14"><span data-lake-id="u0b8ee257" id="u0b8ee257">比如地址如果都细化拆分成省、市、区、街道、小区等等多个字段这就是符合第一范式的， 如果地址就是一个字段，那就不符合了。</span></li>
  </ul>
  <ul list="ue3a00ff8" start="2">
   <li fid="u8bee48ee" data-lake-id="u09c7e613" id="u09c7e613"><span data-lake-id="u7d782be9" id="u7d782be9">第二范式（2NF）是说，数据库表中的每个实例或记录必须可以被唯一地区分，说白了就是要有主键，其他的字段都依赖于主键。</span></li>
   <li fid="u8bee48ee" data-lake-id="ud8d934c0" id="ud8d934c0"><span data-lake-id="u07f1917d" id="u07f1917d">第三范式（3NF）是说，任何非主属性不依赖于其它非主属性，也就是说，非主键外的所有字段必须互不依赖</span></li>
  </ul>
  <p data-lake-id="u508dfba8" id="u508dfba8"><span data-lake-id="u6321c375" id="u6321c375">​</span><br></p>
  <p data-lake-id="u8ccbe8a8" id="u8ccbe8a8"><span data-lake-id="u7fe42a1e" id="u7fe42a1e">如果我们在做表结构设计的时候，完全遵守数据库三范式，确实可以避免一些写时异常，提升一些写入性能，但是同时也会丢失一些读取性能。</span></p>
  <p data-lake-id="u307d51c7" id="u307d51c7"><span data-lake-id="u7d0492b6" id="u7d0492b6">​</span><br></p>
  <p data-lake-id="uf7848ebb" id="uf7848ebb"><span data-lake-id="u1220f522" id="u1220f522">因为在遵守范式的数据库设计中，表中不能有任何冗余字段，这就使得查询的时候就会经常有多表关联查询，这无疑是比较耗时的。</span></p>
  <p data-lake-id="ufdc07496" id="ufdc07496"><span data-lake-id="ue96e33f7" id="ue96e33f7">​</span><br></p>
  <p data-lake-id="uf53d522f" id="uf53d522f"><span data-lake-id="ud25dfb07" id="ud25dfb07">于是就有了反范式化。所谓反范式化，是一种针对遵从设计范式的数据库的性能优化策略。</span></p>
  <p data-lake-id="u6ed5b47f" id="u6ed5b47f"><span data-lake-id="ue0784ee4" id="ue0784ee4">​</span><br></p>
  <p data-lake-id="ud55d2205" id="ud55d2205"><span data-lake-id="u17dc2617" id="u17dc2617">也就是说，反范式化不等于非范式化，反范式化一定发生在满足范式设计的基础之上。前者相当于先遵守所有规则，再进行局部调整。</span></p>
  <p data-lake-id="u8fc998f0" id="u8fc998f0"><span data-lake-id="u3383197c" id="u3383197c">​</span><br></p>
  <p data-lake-id="ud1702f51" id="ud1702f51"><span data-lake-id="ua89b3ae5" id="ua89b3ae5">比如我们可以在表中增加一些冗余字段，方便我们进行数据查询，而不再需要经常做多表join，但同时，这也会带来一个问题，那就是这些冗余字段之间的一致性如何保证，这个问题本来在遵守范式的设计中是不会有的，一旦做了反范式，那就需要开发者自行解决了。</span></p>
  <p data-lake-id="uc0d393c6" id="uc0d393c6"><span data-lake-id="u56589fe9" id="u56589fe9">​</span><br></p>
  <p data-lake-id="u0fdb6e9d" id="u0fdb6e9d"><span data-lake-id="u846f3b19" id="u846f3b19">反范式其实本质上是软件开发中一个比较典型的方案，那就是"用空间换时间"，通过做一些数据冗余，来提升查询速度。</span></p>
  <p data-lake-id="u7ddfcb0e" id="u7ddfcb0e"><span data-lake-id="uae15ffad" id="uae15ffad">​</span><br></p>
  <p data-lake-id="ubb846434" id="ubb846434"><span data-lake-id="ua389dadb" id="ua389dadb">在互联网业务中，比较典型的就是数据量大，并发高，并且通常查询的频率要远高于写入的频率，所以适当的做一些反范式，通过做一些字段的冗余，可以提升查询性能，降低响应时长，从而提升并发度。</span></p>
 </body>
</html>